package com.xy.http.volley;

import android.content.Context;
import android.graphics.Bitmap;

import androidx.collection.LruCache;

import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by XuYang
 * 2023/4/20
 * Email:544066591@qq.com
 */
public class VolleySingleton {

    private static VolleySingleton instance;
    private RequestQueue requestQueue;
    private ImageLoader imageLoader;
    private static Context ctx;

    private VolleySingleton(Context context) {
        ctx = context;
        requestQueue = getRequestQueue();

        imageLoader = new ImageLoader(requestQueue,
                new ImageLoader.ImageCache() {
                    private final LruCache<String, Bitmap>
                            cache = new LruCache<String, Bitmap>(20);

                    @Override
                    public Bitmap getBitmap(String url) {
                        return cache.get(url);
                    }

                    @Override
                    public void putBitmap(String url, Bitmap bitmap) {
                        cache.put(url, bitmap);
                    }
                });
    }

    public static VolleySingleton getInstance(Context context) {
        if (instance == null) {
            synchronized (VolleySingleton.class) {
                if (instance == null) {
                    instance = new VolleySingleton(context);
                }
            }
        }
        return instance;
    }

    public RequestQueue getRequestQueue() {
        if (requestQueue == null) {
            requestQueue = Volley.newRequestQueue(ctx.getApplicationContext());
        }
        return requestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {
        getRequestQueue().add(req);
    }

    public ImageLoader getImageLoader() {
        return imageLoader;
    }

    public void stringRequest(int method, String url, int timeout, VolleyListener<String> listener) {
        StringRequest stringRequest = new StringRequest(method, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        listener.onResponse(response);
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                listener.onErrorResponse(error);
            }
        });
        stringRequest.setRetryPolicy(new DefaultRetryPolicy(timeout, 0, 1.0F));
        addToRequestQueue(stringRequest);
    }

    public void stringRequest(int method, String url, int timeout, Map<String, String> headers, VolleyListener<String> listener) {
        StringRequest stringRequest = new StringRequest(method, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        listener.onResponse(response);
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                listener.onErrorResponse(error);
            }
        }) {
            @Override
            public Map<String, String> getHeaders() {
                Map<String, String> map = headers;
                if (map == null) {
                    map = new HashMap<>();
                }
                return map;
            }
        };
        stringRequest.setRetryPolicy(new DefaultRetryPolicy(timeout, 0, 1.0F));
        addToRequestQueue(stringRequest);
    }

    public void stringRequest(int method, String url, Map<String, String> params, int timeout, VolleyListener<String> listener) {
        StringRequest stringRequest = new StringRequest(method, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        listener.onResponse(response);
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                listener.onErrorResponse(error);
            }
        }) {
            @Override
            protected Map<String, String> getParams() {
                Map<String, String> map = params;
                if (map == null) {
                    map = new HashMap<>();
                }
                return map;
            }
        };
        stringRequest.setRetryPolicy(new DefaultRetryPolicy(timeout, 0, 1.0F));
        addToRequestQueue(stringRequest);
    }

    public void stringRequest(int method, String url, Map<String, String> params, int timeout, Map<String, String> headers, VolleyListener<String> listener) {
        StringRequest stringRequest = new StringRequest(method, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        listener.onResponse(response);
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                listener.onErrorResponse(error);
            }
        }) {
            @Override
            protected Map<String, String> getParams() {
                Map<String, String> map = params;
                if (map == null) {
                    map = new HashMap<>();
                }
                return map;
            }

            @Override
            public Map<String, String> getHeaders() {
                Map<String, String> map = headers;
                if (map == null) {
                    map = new HashMap<>();
                }
                return map;
            }
        };
        stringRequest.setRetryPolicy(new DefaultRetryPolicy(timeout, 0, 1.0F));
        addToRequestQueue(stringRequest);
    }

    public void JsonObjectRequest(int method, String url, JSONObject jsonObject, int timeout, VolleyListener<JSONObject> listener) {
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
                (method, url, jsonObject, new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject response) {
                        listener.onResponse(response);
                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        listener.onErrorResponse(error);
                    }
                });
        jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(timeout, 0, 1.0F));
        addToRequestQueue(jsonObjectRequest);
    }

    public void JsonObjectRequest(int method, String url, JSONObject jsonObject, int timeout, Map<String, String> headers, VolleyListener<JSONObject> listener) {
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
                (method, url, jsonObject, new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject response) {
                        listener.onResponse(response);
                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        listener.onErrorResponse(error);
                    }
                }) {
            @Override
            public Map<String, String> getHeaders() {
                Map<String, String> map = headers;
                if (map == null) {
                    map = new HashMap<>();
                }
                return map;
            }
        };
        jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(timeout, 0, 1.0F));
        addToRequestQueue(jsonObjectRequest);
    }
}
